// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

using System;
using JetBrains.Annotations;

namespace SnapObjects.Data
{
    internal class ColumnModification
    {
        private string _parameterName;
        private string _originalParameterName;
        private readonly Func<bool, string> _generateParameterName;

        public ColumnModification(
            [NotNull] IUpdatableModel updatableModel,
            [NotNull] IUpdatableProperty property,
            [NotNull] Func<bool, string> generateParameterName,
            bool isRead,
            bool isWrite,
            bool isKey,
            bool isIdentity,
            bool isCondition,
            bool isConcurrencyToken,
            bool useOriginalValueParameter,
            bool useCurrentValueParameter)
        {
            this.UpdatableModel = updatableModel;
            this.Property = property;
            _generateParameterName = generateParameterName;

            this.MappedColumn = updatableModel.UppercaseIdentifier ?
                property.MappedColumn?.ToUpper() :
                property.MappedColumn;

            this.IsRead = isRead;
            this.IsWrite = isWrite;
            this.IsKey = isKey;
            this.IsIdentity = isIdentity;
            this.IsCondition = isCondition;
            this.IsConcurrencyToken = isConcurrencyToken;
            this.UseOriginalValueParameter = useOriginalValueParameter;
            this.UseCurrentValueParameter = useCurrentValueParameter;
        }

        public virtual string MappedColumn { get; }

        public virtual IUpdatableProperty Property { get; }

        public virtual IUpdatableModel UpdatableModel { get; }

        public virtual bool IsRead { get; }

        public virtual bool IsWrite { get; }

        public virtual bool IsCondition { get; }

        public virtual bool IsConcurrencyToken { get; }

        public virtual bool IsKey { get; }

        public virtual bool IsIdentity { get; }

        public virtual bool UseOriginalValueParameter { get; }

        public virtual bool UseCurrentValueParameter { get; }

        public virtual string ParameterName
            => _parameterName ?? (_parameterName = _generateParameterName(false));

        public virtual string OriginalParameterName
            => _originalParameterName ?? (_originalParameterName = _generateParameterName(true));

        public virtual object OriginalValue => this.UpdatableModel.GetOriginalValue(this.Property);

        public virtual object CurrentValue => this.UpdatableModel.GetCurrentValue(this.Property);
    }
}
